package club.jdiy.core.storage;

import club.jdiy.utils.FileUtils;
import lombok.Getter;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.function.Consumer;

/**
 * JDiy附件存储接口类
 *
 * @author ziquee(子秋) QQ号:39886616 主页: http://www.jdiy.club
 * @version 20200725
 */
@SuppressWarnings("unused")
public interface Store {
    Store.Entry get(String field);

    @AutoSave
    void set(String field, MultipartFile file, String fileName) throws IOException;
    @AutoSave
    void set(String field, MultipartFile file, String fileName,Consumer<File> c) throws IOException;

    @AutoSave
    void add(String field, MultipartFile mFile) throws IOException;

    @AutoSave
    void add(String field, MultipartFile mFile, String fileName) throws IOException;
    @AutoSave
    void add(String field, MultipartFile mFile, String fileName,Consumer<File> c) throws IOException;

    @AutoSave
    void add(String field, File file) throws IOException;

    @AutoSave
    void add(String field, File file, String fileName) throws IOException;

    @AutoSave
    void del(String field) throws IOException;

    @AutoSave
    void del(String field, String key) throws IOException;

    @AutoSave
    void delAll();

    @AutoSave
    void set(String field, File file) throws IOException;

    @AutoSave
    void set(String field, File file, String fileName) throws IOException;

    @AutoSave
    void set(String field, MultipartFile file) throws IOException;

    /**
     * 此方法上传附件并直接返回路径．　不写 jdiy_store
     */
    String put(MultipartFile file, String fileName) throws IOException;
    String put(MultipartFile file, String fileName, Consumer<File> d) throws IOException;
    /**
     * 此方法上传附件并直接返回路径．　不写 jdiy_store
     */
    String put(File file, String fileName) throws IOException;

    String put(byte[] bytes, String fileName) throws IOException;

    class Entry {
        private final EntryItem[] items;

        Entry(EntryItem[] entries) {
            this.items = entries;
        }

        public EntryItem[] getItems() {
            return items;
        }

        @Override
        public String toString() {
            return getUrl();
        }

        public String getUrl() {
            return items == null || items.length < 1 ? null : items[0].getUrl();
        }

        public String[] getUrls() {
            int i = 0;
            String[] urls = new String[items.length];
            for (EntryItem ei : items) urls[i++] = ei.url;
            return urls;
        }

        public String getName() {
            return items == null || items.length < 1 ? null : items[0].getName();
        }

        public String getSizeStr() {
            return items == null || items.length < 1 ? null : items[0].getSizeStr();
        }

        public long getSize() {
            return items == null || items.length < 1 ? 0 : items[0].getSize();
        }

        public String getKey() {
            return items == null || items.length < 1 ? null : items[0].getKey();
        }

        public String getExt() {
            return items == null || items.length < 1 ? null : items[0].getExt();
        }
    }

    @Getter
    class EntryItem extends StoreMetaData.StoreItem {
        private final String url;
        private final String name;
        private final String sizeStr;

        EntryItem(StoreMetaData.StoreItem ai, String url) {
            super(ai.getKey(), ai.getSize(), ai.getExt());
            this.sizeStr = FileUtils.sizeStr(getSize());
            this.name = ai.getKey().substring(ai.getKey().lastIndexOf("/") + 1);
            this.url = url;
        }

        @Override
        public String toString() {
            return this.url;
        }
    }


    @Target(ElementType.METHOD)
    @Retention(value = RetentionPolicy.RUNTIME)
    @interface AutoSave {
    }

}
